use std::collections::HashSet;

fn get_priority(item: char) -> i32 {
    let a_ascii = 'a' as i32;
    let z_ascii = 'z' as i32;
    let upper_a_ascii = 'A' as i32;
    let upper_z_ascii = 'Z' as i32;

    let item_ascii = item as i32;
    if item_ascii >= a_ascii && item_ascii <= z_ascii {
        return 1 + item_ascii - a_ascii;
    } else if item_ascii >= upper_a_ascii && item_ascii <= upper_z_ascii {
        return 27 + item_ascii - upper_a_ascii;
    }

    panic!("Unsupport item '{}'", item);
}

#[allow(unused)]
fn part1() {
    let input = include_str!("../input.txt");
    let sum = input
        .lines()
        .map(|line| -> i32 {
            let chars = line.chars().collect::<Vec<char>>();
            let mut package1 = HashSet::<char>::new();
            for &char in &chars[0..(chars.len() / 2)] {
                package1.insert(char);
            }
            for &char in &chars[(chars.len()/2)..] {
                if package1.contains(&char) {
                    return get_priority(char);
                }
            }
            0
        })
        .sum::<i32>();
    println!("Part 1: {}", sum);
}

#[allow(unused)]
fn part2() {
    let input = include_str!("../input.txt");
    let sum = input
        .lines()
        .collect::<Vec<_>>()
        .chunks(3)
        .map(|rucksacks| -> i32 {
            let mut prioritys: [i32; 53] = [0; 53];
            
            for rucksack in rucksacks {
                let items = rucksack.chars().collect::<HashSet<char>>();
                for item in items {
                    let priority = get_priority(item) as usize;
                    prioritys[priority] += 1;
                }
            }

            for (priority, times) in prioritys.into_iter().enumerate() {
                if times == 3 {
                    return priority as i32;
                }
            }

            0
        })
        .sum::<i32>();
    println!("Part 2: {}", sum);
}

fn main() {
    part1();
    part2();
}
